package king.dominic.jlibrary.http;


import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import king.dominic.jlibrary.util.Ref;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import okio.BufferedSource;
import okio.Okio;
import retrofit2.Converter;
import retrofit2.Retrofit;

/**
 * Created by DominicKing on 2017/11/7.
 * FastJsonConverterFactory
 */

public class FastJsonConverterFactory extends Converter.Factory {

    public static FastJsonConverterFactory create() {
        return new FastJsonConverterFactory();
    }

    /**
     * 需要重写父类中responseBodyConverter，该方法用来转换服务器返回数据
     */
    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
        return new FastJsonResponseBodyConverter<>(type);
    }

    /**
     * 需要重写父类中responseBodyConverter，该方法用来转换发送给服务器的数据
     */
    @Override
    public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
        return new FastJsonRequestBodyConverter<>();
    }

    public static class FastJsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
        private final Type type;

        private FastJsonResponseBodyConverter(Type type) {
            this.type = type;
        }

        /*
        * 转换方法
        */
        @SuppressWarnings("unchecked")
        @Override
        public T convert(ResponseBody value) throws IOException {
            BufferedSource bufferedSource = Okio.buffer(value.source());
            String tempStr = bufferedSource.readUtf8();
            bufferedSource.close();
            Class json = JSON();
            if(json==null)return null;
            Object result = Ref.cStaticMethod(json, "parseObject", tempStr, type);
            if(result==null)return null;
            return (T) result;
        }
    }

    public static class FastJsonRequestBodyConverter<T> implements Converter<T, RequestBody> {
        private static final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8");

        @Override
        public RequestBody convert(T value) throws IOException {
            Class json = JSON();
            if(json==null)return null;
            Object result = Ref.cStaticMethod(json, "toJSONBytes", value);
            if(result==null)return null;
            return RequestBody.create(MEDIA_TYPE, (byte[]) result);
        }
    }

    private static Class JSON() {
        try {
            return Class.forName("com.alibaba.fastjson.JSON");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }
}